package com.bird.system.application.auth

import cn.dev33.satoken.stp.StpUtil
import cn.hutool.captcha.CaptchaUtil
import cn.hutool.core.util.IdUtil
import com.bird.component.cache.component.CacheComponent
import com.bird.component.cache.constant.CacheConstant
import com.bird.component.lang.common.exception.ServiceException
import com.bird.system.application.auth.pl.*
import com.bird.system.application.common.pl.AuthUserInfo
import org.springframework.stereotype.Service
import java.util.concurrent.TimeUnit

@Service
class AuthCommandService(val cacheComponent: CacheComponent, val authAppGateway: AuthAppGateway)  {
    /**
     * 生成验证码
     */
    fun generateVerificationCode(): Pair<String, String> {
        val fastUUID = IdUtil.fastSimpleUUID()
        // 生成验证码
        val createCircleCaptcha = CaptchaUtil.createCircleCaptcha(200, 100, 4, 20)
        // 存储验证码
        cacheComponent.setValue(
            key = CacheConstant.VERIFICATION_CODE + fastUUID,
            value = createCircleCaptcha.code,
            timeout = TimeUnit.MINUTES.toSeconds(2)
        )
        return Pair(fastUUID, createCircleCaptcha.imageBase64)
    }

    /**
     * 登录
     */
    fun login(loginReqeust: LoginReqeust): LoginResponse {
        // 获取验证码
        val verificationCode = cacheComponent.getValue<String>(CacheConstant.VERIFICATION_CODE + loginReqeust.captchaKey)
            ?: throw ServiceException(AuthStatusInfo.VERIFICATION_CODE_INVALID)
        // 清除验证码
        cacheComponent.delete(CacheConstant.VERIFICATION_CODE + loginReqeust.captchaKey)
        // 验证码校验
        if (verificationCode != loginReqeust.captchaCode) {
            throw ServiceException(AuthStatusInfo.VERIFICATION_CODE_ERROR)
        }
        // 根据用户名密码获取用户信息
        val authUserInfo: AuthUserInfo = (authAppGateway.oneUser(loginReqeust.username, loginReqeust.password)
            ?: throw ServiceException(AuthStatusInfo.USERNAME_OR_PASSWORD_ERROR))
        // 登录
        StpUtil.login(authUserInfo.id!!)
        // 返回登录信息
        return authUserInfo.toLoginResponse(StpUtil.getTokenValue(), StpUtil.getTokenTimeout())

    }
}